﻿using Foxit.PDF;
using Foxit.PDF.IO;
using Foxit.PDF.PageElements;
using Sustainalytics.ClientDW.Entities;
using System.Collections.Generic;
using Sustainalytics.Reporting.Framework;
using Sustainalytics.ESG.Entities;

namespace Sustainalytics.ReportGenerator.BL
{
    public class BenchmarkChart : PageElement
    {
        public float Left { get; set; }
        public float Top { get; set; }

        public int AssesmentId { get; set; }
        public int[] Values { get; set; }

        public bool ShowLegend { get; set; }

        public BenchmarkChart(float left, float top, int assesmentId, int[] values, bool showLegend)
        {
            Left = left;
            Top = top;
            AssesmentId = assesmentId;
            Values = values;
            ShowLegend = showLegend;
        }

        private Group Chart()
        {
            var elements = new Group();
            var verticalLineHeight = Values.Length == 5
                ? (18f * Values.Length + 7f)
                : 88f;
            const float lineSize = 1f;
            var top = Top + 30f;
            var left = Left + 90f;
            var lineColor = RgbColor.Black;

            const float titleFontSize = 8f;
            const float labelSize = 7f;

            if (ShowLegend)
            {
                elements.Add(new Rectangle(Left, Top-7f, 8f, 8f, new RgbColor(20, 167, 157), new RgbColor(20, 167, 157)));
                elements.Add(new Label("Company’s Performance", Left + 20f, Top-10f, 100f,
                    labelSize + 2f, Fonts.CalibriRegular, labelSize, TextAlign.Left, RgbColor.Black));
            }

            var verticalTitle = Values.Length == 5
                ? "ESG ASSESSMENT"
                : "CONTROVERSY ASSESSMENT";

            elements.Add(new Label(verticalTitle, Left, top + verticalLineHeight, verticalLineHeight+15f,
            titleFontSize + 2f, Fonts.CalibriRegular, titleFontSize, TextAlign.Center, RgbColor.Black)
            { Angle = -90 });

            elements.Add(new Label("0%", left - 10f, Top , 20f,
                    labelSize + 2f, Fonts.CalibriLight, labelSize, TextAlign.Center));
            elements.Add(new Line(left, top-20f, left, top + verticalLineHeight-20f, lineSize, lineColor));
            lineColor = RgbColor.Silver;
            left += 50f;
            elements.Add(new Label("50%", left - 10f, Top , 20f,
                    labelSize + 2f, Fonts.CalibriLight, labelSize, TextAlign.Center));
            elements.Add(new Line(left, top-20f, left, top + verticalLineHeight-20f, lineSize, lineColor));
            left += 50f;
            elements.Add(new Label("100%", left -10f, Top , 20f,
                    labelSize + 2f, Fonts.CalibriLight, labelSize, TextAlign.Center));
            elements.Add(new Line(left, top-20f, left, top + verticalLineHeight-20f, lineSize, lineColor));


            left = Left + 90f;
            top += 10f;
       
            var assesments = Values.Length == 5
                ? GetSustainabilityAssessments()
                : GetControversyAssessments();

            for (var index = 0; index < assesments.Length; index++)
            {
                var font = Fonts.CalibriLight;
                var labelColor = RgbColor.Black;
                var barColor = RgbColor.Silver;
                if (assesments[index].Id == AssesmentId)
                {
                    font = Fonts.CalibriBold;
                    labelColor = new RgbColor(20, 167, 157);
                    barColor = new RgbColor(20, 167, 157);
                }

                var value = Values[index];
                elements.Add(new Label(assesments[index].Name, Left + 10f, top-20f, 70f,
                labelSize + 2f, font, labelSize, TextAlign.Right, labelColor));
                elements.Add(new Rectangle(left + 1f, top-20f, value, 8f, barColor, barColor));
                var topDif = Values.Length == 5
                ? 18f
                : 13f;
                top += topDif;

            }
            top += 10f;
           

            elements.Add(new Label("INDUSTRY DISTRIBUTION", left, top-10f, 100f,
               titleFontSize + 2f, Fonts.CalibriRegular, titleFontSize, TextAlign.Center, RgbColor.Black));
            return elements;
        }

        private static RPAssessment[] GetSustainabilityAssessments()
        {
            var assesments = new List<RPAssessment>()
            {
                new RPAssessment()
                {
                    Id = 1,
                    Name = "Leader"
                },
                new RPAssessment()
                {
                    Id = 2,
                    Name = "Outperformer"
                },
                new RPAssessment()
                {
                    Id = 3,
                    Name = "Average Performer"
                },
                new RPAssessment()
                {
                    Id = 4,
                    Name = "Underperformer"
                },
                new RPAssessment()
                {
                    Id = 5,
                    Name = "Laggard"
                }
            };

            return assesments.ToArray();
        }

        private static RPAssessment[] GetControversyAssessments()
        {
            var assesments = new List<RPAssessment>()
            {
                new RPAssessment()
                {
                    Id = 0,
                    Name = "None"
                },
                new RPAssessment()
                {
                    Id = 1,
                    Name = "Low"
                },
                new RPAssessment()
                {
                    Id = 2,
                    Name = "Moderate"
                },
                new RPAssessment()
                {
                    Id = 3,
                    Name = "Significant"
                },
                new RPAssessment()
                {
                    Id = 4,
                    Name = "High"
                },
                new RPAssessment()
                {
                    Id = 5,
                    Name = "Severe"
                }
            };

            return assesments.ToArray();
        }

        public override void Draw(PageWriter writer)
        {
            var elements = Chart();

            writer.Write_q_(true);
            elements.Draw(writer);
            writer.Write_Q(true);
        }
    }

    public class ThematicBenchmarkChart : PageElement
    {
        public float Left { get; set; }
        public float Top { get; set; }

        public int[] ThemeScores { get; set; }
        public int[] CompanyThemeAssesments { get; set; }
        public int[][] PeersThemeAssesments { get; set; }

        public ThematicBenchmarkChart(float left, float top, int[] themeScores, int[] companyThemeAssesments, int[][] peersThemeAssesments)
        {
            Left = left;
            Top = top;
            ThemeScores = themeScores;
            CompanyThemeAssesments = companyThemeAssesments;
            PeersThemeAssesments = peersThemeAssesments;
        }

        private Group Chart()
        {
            const float columnWidth = 75f;
            const string title = "<p><b>THEMATIC BENCHMARK</b></p>";
            const string helpText = "<p><font color='#000000'>For each sustainability theme, the graph below indicates the percentage of companies in the global industry peer group that fall within each sustainability assessment category.</font></p>";
            const float helpTextWidth = 150f;
            const float titleFontSize = 12f;
            const float themeFontSize = 8f;
            const float labelSize = 7f;


            var style = new FormattedTextAreaStyle(Fonts.CalibriFontFamily, 6.5f, false)
            {
                Paragraph = { Align = TextAlign.Justify, Indent = 0, SpacingAfter = 5, AllowOrphanLines = false }
            };


            var elements = new Group();


            elements.Add(new FormattedTextArea(title, Left, Left, helpTextWidth, titleFontSize + 2f, Fonts.CalibriFontFamily, titleFontSize, false));


            var formattedTextArea = new FormattedTextArea(helpText, Left, Top + 20, helpTextWidth, 50f, style);
            var textHeight = formattedTextArea.GetRequiredHeight() + 5f;


            elements.Add(formattedTextArea);

            float top;

            const float verticalLineHeight = 75f ;
            const float lineSize = 1f;
            const float labelWidth = 70f;

            var left = Left + 130f + labelWidth + 10f;
            RgbColor lineColor;

            var themeNames = new[] { "ENVIRONMENT", "SOCIAL", "GOVERNANCE" };

            for (var theme = 0; theme < 3; theme++)
            {
                top = Top;
                elements.Add(new Label(themeNames[theme], left, top, 100f,
                   themeFontSize + 2f, Fonts.CalibriRegular, themeFontSize, TextAlign.Left, RgbColor.Black));

                top += 15;

                elements.Add(new FormattedTextArea($"<p>{ThemeScores[theme]} <font color='#000000' PointSize=8> out of 100</font></p>",
                     left, top, columnWidth, 18f + 2f, Fonts.CalibriLightFontFamily, 18f, false));

                top += 30f;
                lineColor = RgbColor.Black;

                elements.Add(new Label("0%", left - 10f, top, 20f,
                    labelSize + 2f, Fonts.CalibriLight, labelSize, TextAlign.Center));
                elements.Add(new Line(left, top + 10f, left, top + 10f + verticalLineHeight, lineSize, lineColor));
                lineColor = RgbColor.Silver;
                left += columnWidth / 2;
                elements.Add(new Label("50%", left - 10f, top, 20f,
                    labelSize + 2f, Fonts.CalibriLight, labelSize, TextAlign.Center));
                elements.Add(new Line(left, top + 10f, left, top + 10f + verticalLineHeight, lineSize, lineColor));
                left += columnWidth / 2;
                elements.Add(new Label("100%", left - 10f, top, 20f,
                    labelSize + 2f, Fonts.CalibriLight, labelSize, TextAlign.Center));
                elements.Add(new Line(left, top + 10f, left, top + 10f + verticalLineHeight, lineSize, lineColor));

                left += 50f;
            }


            top = Top + 62f;


            var assesments = GetSustainabilityAssessments();

            for (var index = 0; index < assesments.Length; index++)
            {
                left = Left + 130f + labelWidth + 10f;

                elements.Add(new Label(assesments[index].Name, Left + 130f, top, labelWidth,
                    labelSize + 2f, Fonts.CalibriLight, labelSize, TextAlign.Right, RgbColor.Black));


                for (var theme = 0; theme < 3; theme++)
                {
                    var barColor = RgbColor.Silver;
                    if (assesments[index].Id == CompanyThemeAssesments[theme])
                    {
                        barColor = new RgbColor(20, 167, 157);
                    }

                    var value = PeersThemeAssesments[theme][index];

                    elements.Add(new Rectangle(left + 1f, top, value * (columnWidth / 100), 6f, barColor, barColor));

                    left += columnWidth + 50f;
                }

                top += 15f;
            }

            top += 10f;
            left = Left + 130f + labelWidth + 10f;
            var width = (columnWidth + 50f) * 3;

            elements.Add(new Label("INDUSTRY DISTRIBUTION", left-50f, top-10f, width,
                themeFontSize + 2f, Fonts.CalibriRegular, themeFontSize, TextAlign.Center, RgbColor.Black));



            return elements;
        }

        private static RPAssessment[] GetSustainabilityAssessments()
        {
            var assesments = new List<RPAssessment>()
            {
                new RPAssessment()
                {
                    Id = 1,
                    Name = "Leader"
                },
                new RPAssessment()
                {
                    Id = 2,
                    Name = "Outperformer"
                },
                new RPAssessment()
                {
                    Id = 3,
                    Name = "Average Performer"
                },
                new RPAssessment()
                {
                    Id = 4,
                    Name = "Underperformer"
                },
                new RPAssessment()
                {
                    Id = 5,
                    Name = "Laggard"
                }
            };

            return assesments.ToArray();
        }

        public override void Draw(PageWriter writer)
        {
            var elements = Chart();

            writer.Write_q_(true);
            elements.Draw(writer);
            writer.Write_Q(true);
        }
    }
}
